﻿namespace com.u3d.bases.ai
{
    using com.game;
    using com.game.basic;
    using com.game.basic.events;
    using com.game.data;
    using com.game.module.Dungeon;
    using com.game.module.fight.arpg;
    using com.game.module.fight.vo;
    using com.game.module.map;
    using com.game.module.WiFiPvP;
    using com.game.vo;
    using com.liyong;
    using com.u3d.bases.controller;
    using com.u3d.bases.display;
    using com.u3d.bases.display.character;
    using com.u3d.bases.display.controler;
    using com.u3d.bases.fsmUtil;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using UnityEngine;
    using UnityLog;

    public abstract class AiControllerBase : MonoBehaviour, IAiController
    {
        protected int _ai_status;
        protected AiEnum.AiScriptType _ai_type;
        private com.game.vo.BaseRoleVo _baseRoleVo;
        protected readonly List<CacheAiBehavior> _CacheAiBehaviorList = new List<CacheAiBehavior>();
        protected bool _canDisrupt = true;
        protected ActionDisplay _currentTargetDisplay;
        private bool _isAiEnable;
        private static bool _isDictInitialized;
        protected bool _isInitialized;
        protected bool _lastIsAiEnable;
        protected float _loop_interval;
        protected int _nowStatus;
        protected int _nowStatusHash;
        protected float _nowTime;
        protected Transform _selfTransform;
        protected float _stopTime;
        protected uint _targetLastCamp = 0x3e7;
        protected com.game.vo.BaseRoleVo _targetVo;
        protected float _tick;
        [CompilerGenerated]
        private static Func<bool> <>f__am$cache1E;
        [CompilerGenerated]
        private static Func<System.Type, bool> <>f__am$cache1F;
        private static readonly Dictionary<string, System.Type> aiTargetDict = new Dictionary<string, System.Type>();
        protected List<ActionDisplay> attackable_list = new List<ActionDisplay>();
        protected ActionControler MeController;
        protected readonly vp_Timer.Handle timeHandle = new vp_Timer.Handle();

        protected AiControllerBase()
        {
        }

        private static bool AddAiScriptInArena(GameObject go, BaseDisplay display)
        {
            return ((display is PlayerDisplay) && DoAddAiScript(go, display, "PlayerArenaAi"));
        }

        private static bool AddAiScriptInPVE(GameObject go, BaseDisplay display)
        {
            SysDungeonMissionVo curMissionSysVo = DungeonMgr.Instance.curMissionSysVo;
            if (curMissionSysVo == null)
            {
                return false;
            }
            string aiScript = string.Empty;
            if ((display is MeDisplay) || (display is PlayerDisplay))
            {
                aiScript = curMissionSysVo.role_ai;
            }
            else
            {
                if (!(display is MonsterDisplay))
                {
                    return false;
                }
                switch (display.GetMeVoByType<MonsterVo>().MonsterVO.type)
                {
                    case 1:
                        aiScript = curMissionSysVo.monster_ai;
                        break;

                    case 2:
                    case 5:
                        aiScript = "StaticItemAi";
                        break;

                    case 3:
                        aiScript = "TowerAi";
                        break;

                    case 4:
                        aiScript = "PrivateAi";
                        break;

                    case 6:
                        aiScript = "SummonMonsterAi";
                        break;
                }
            }
            return DoAddAiScript(go, display, aiScript);
        }

        private static bool AddAiScriptInPVP(GameObject go, BaseDisplay display)
        {
            if (display.GetMeVoByType<com.game.vo.BaseRoleVo>().Camp != 0)
            {
                return false;
            }
            SysWifiPvpVo pvpTemplate = WifiPvpManager.Instance.PvpTemplate;
            if (pvpTemplate == null)
            {
                return false;
            }
            string aiScript = string.Empty;
            if (display is MeDisplay)
            {
                aiScript = pvpTemplate.my_ai_script;
            }
            else
            {
                if (!(display is MonsterDisplay))
                {
                    return false;
                }
                switch (display.GetMeVoByType<MonsterVo>().MonsterVO.type)
                {
                    case 1:
                        aiScript = "MonsterAi";
                        break;

                    case 2:
                    case 5:
                        aiScript = "StaticItemAi";
                        break;

                    case 3:
                        aiScript = pvpTemplate.tower_ai_script;
                        break;

                    case 4:
                        aiScript = pvpTemplate.private_ai_script;
                        break;

                    case 6:
                        aiScript = "SummonMonsterAi";
                        break;
                }
            }
            return DoAddAiScript(go, display, aiScript);
        }

        public static bool AddProperAI(GameObject go, ActionDisplay display)
        {
            StateMachineUtil.AddStateMachine(go, display);
            if (AppMap.Instance.IsInWifiPVP)
            {
                return AddAiScriptInPVP(go, display);
            }
            if (AppMap.Instance.IsInArena)
            {
                return AddAiScriptInArena(go, display);
            }
            return AddAiScriptInPVE(go, display);
        }

        protected abstract void AiStateDecision(float timeElapsed);
        protected void AiStateDecision(bool skipThink, float timeElapsed)
        {
            if (!skipThink)
            {
                this.AiStateDecision(timeElapsed);
            }
        }

        protected virtual void Awake()
        {
            this.RegisterToDungeonMgr();
        }

        public virtual void BeAttacked(ActionVo attackVo, float time = 0)
        {
            time = (time == 0f) ? this._nowTime : time;
            this.LastBeAttackedTime = time;
        }

        private static void CallbackSetAiThink(ActionControler ac)
        {
            ac.AiController.SetAiStatus(AiEnum.PlayerAiStatus.THINK);
        }

        public static void CancelAllTimer()
        {
            vp_Timer.CancelAll("DoAddHp");
        }

        public virtual void CastSkill(SysSkillBaseVo skillVo, float time = 0)
        {
            if (skillVo.subtype != 1)
            {
                time = (time == 0f) ? this._nowTime : time;
                if (skillVo.is_skill)
                {
                    this.LastUseSkillTime = time;
                }
                else
                {
                    this.LastUseAttackTime = time;
                }
            }
        }

        protected virtual bool CheckCacheAiBehavior()
        {
            return (this._CacheAiBehaviorList.Count > 0);
        }

        protected virtual bool CheckCanUseAi()
        {
            return (this.IsAiEnable && !this.BaseRoleVo.stateInfo.ShouldPauseAI);
        }

        protected virtual bool CheckIsDead()
        {
            return ((this._nowStatus == 11) || (this._nowStatus == 0x13));
        }

        protected virtual bool CheckIsDoingSkill()
        {
            return StatuControllerBase.IsStatusHashInFight(this._nowStatusHash);
        }

        protected virtual bool CheckIsInFight()
        {
            bool flag = (this._nowStatus >= 3) && (this._nowStatus <= 6);
            bool flag2 = (this._nowStatus >= 10) && (this._nowStatus <= 14);
            return (flag && flag2);
        }

        protected virtual bool CheckIsInRunOrIdleOrHurt()
        {
            return (((this._nowStatus == 0) || (this._nowStatus == 1)) || ((this._nowStatus >= 10) && (this._nowStatus <= 14)));
        }

        protected virtual bool CheckShouldSkipThink()
        {
            return false;
        }

        public abstract void CleanTargetDisplay();
        public void ClearCacheAiBehavior()
        {
            this._CacheAiBehaviorList.Clear();
        }

        private static bool DoAddAiScript(GameObject go, BaseDisplay display, string aiScript)
        {
            InitAiDict();
            aiScript = aiScript.Replace("Ai", "AiController");
            if (!aiTargetDict.ContainsKey(aiScript))
            {
                return false;
            }
            if (go.GetComponent(aiScript) != null)
            {
                return false;
            }
            AiControllerBase base2 = (AiControllerBase) go.AddComponent(aiScript);
            base2.MeController = display.Controller as ActionControler;
            display.Controller.AiController = base2;
            return true;
        }

        protected virtual bool DoCacheAttack(CacheAiBehavior Elem)
        {
            return false;
        }

        protected virtual bool DoCacheSkill(CacheAiBehavior Elem)
        {
            return false;
        }

        protected virtual bool DoCacheSkillAndUpdateLastUsedTime(CacheAiBehavior Elem)
        {
            return false;
        }

        protected virtual bool EnterStateHandleCachedAiBehavior()
        {
            CacheAiBehavior elem = this._CacheAiBehaviorList[0];
            if ((elem.lastDisplay != this._currentTargetDisplay) && (elem.lastDisplay != null))
            {
                this.ClearCacheAiBehavior();
                return false;
            }
            if ((elem.lastDisplay != null) && elem.lastDisplay.GetMeVoByType<com.game.vo.BaseRoleVo>().IsEmptyHp)
            {
                this.ClearCacheAiBehavior();
                return false;
            }
            bool flag = false;
            bool flag2 = true;
            switch (elem.cacheType)
            {
                case 1:
                    flag = this.DoCacheAttack(elem);
                    flag2 = false;
                    break;

                case 2:
                    flag = this.DoCacheSkill(elem);
                    break;

                case 3:
                    flag = this.DoCacheSkillAndUpdateLastUsedTime(elem);
                    break;

                case 0x63:
                    flag = this.DoCacheSkill(elem);
                    break;
            }
            if (flag)
            {
                if (flag2)
                {
                    this.LastUseSkillTime = this._nowTime;
                }
                else
                {
                    this.LastUseAttackTime = this._nowTime;
                }
                this._CacheAiBehaviorList.RemoveAt(0);
                this._stopTime = 0f;
            }
            return ((this._CacheAiBehaviorList.Count > 1) || flag);
        }

        public virtual void ForceToStopAIAndAllBehavior()
        {
            this.SetAi(false);
        }

        public virtual int GetAiStatus()
        {
            return this._ai_status;
        }

        public ActionDisplay GetLastAttackerOrEnemy()
        {
            ActionDisplay lastTarget = this.MeController.SkillController.LastTarget;
            if (lastTarget != null)
            {
                return lastTarget;
            }
            return this.MeController.LastAttacker;
        }

        public ActionDisplay GetTargetDisplay()
        {
            if (this.IsAiEnable)
            {
                return this._currentTargetDisplay;
            }
            return null;
        }

        protected virtual float GetTargetDistance(ActionDisplay display = null)
        {
            if (display == null)
            {
            }
            display = this._currentTargetDisplay;
            return ((display.Controller != null) ? this.GetTargetDistance(display.GoBase.transform) : float.MaxValue);
        }

        protected virtual float GetTargetDistance(Transform trans)
        {
            return DamageCheck.GetDistance(trans.position, this._selfTransform.position);
        }

        protected virtual float GetTargetSqrMagnitude(ActionDisplay display)
        {
            if (display == null)
            {
            }
            display = this._currentTargetDisplay;
            if (display == null)
            {
                return float.MaxValue;
            }
            return ((display.Controller != null) ? Util.XZSqrMagnitude(display.GoBase.transform, this._selfTransform) : float.MaxValue);
        }

        protected virtual void InformTargeted(ActionDisplay display)
        {
            if ((display.Controller != null) && (display.Controller.AiController != null))
            {
                display.Controller.AiController.Targeted();
            }
        }

        protected virtual void Init()
        {
            this.InitRanges();
            this.InitLoopInterval();
            this.SetAiScriptType();
        }

        private static void InitAiDict()
        {
            if (!_isDictInitialized)
            {
                if (<>f__am$cache1F == null)
                {
                    <>f__am$cache1F = item => (item.Namespace == "com.u3d.bases.ai") && (((item.BaseType == typeof(AiControllerBase)) || (item.BaseType == typeof(MonsterAiController))) || (item.BaseType == typeof(PlayerAiController)));
                }
                IEnumerator<System.Type> enumerator = typeof(AiControllerBase).Assembly.GetTypes().Where<System.Type>(<>f__am$cache1F).GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        System.Type current = enumerator.Current;
                        aiTargetDict.Add(current.Name, current);
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
                _isDictInitialized = true;
            }
        }

        protected abstract void InitLoopInterval();
        protected abstract void InitRanges();
        protected bool IsNearDestination(ActionDisplay dis)
        {
            if (dis.GoBase == null)
            {
                return true;
            }
            Vector3 position = dis.GoBase.transform.position;
            return this.IsNearDestination(position);
        }

        protected bool IsNearDestination(Vector3 dest)
        {
            return (DamageCheck.GetDistance(this._selfTransform.position, dest) < 0.3f);
        }

        protected bool IsNearDestination(Vector3 dest, out float distance)
        {
            distance = DamageCheck.GetDistance(this._selfTransform.position, dest);
            return (distance < 0.3f);
        }

        protected virtual Func<bool> IsNeedToSetNewTargetDisplay()
        {
            if (<>f__am$cache1E == null)
            {
                <>f__am$cache1E = () => true;
            }
            return <>f__am$cache1E;
        }

        public virtual void LookAt(ActionVo attackVo)
        {
            this._selfTransform.LookAtTarget(attackVo.LookAtDestination);
        }

        protected virtual void OnDestroy()
        {
            this.UnregisterFromDungeonMgr();
        }

        protected virtual void PlayerEndBattle()
        {
            if (this.IsInBattle)
            {
                PlayerAiManager.instance.EndBattle(this.MeController.Me as ActionDisplay);
            }
        }

        protected virtual void PrepareWork()
        {
        }

        private static void PrepareworkSetAiCastSkill(ActionControler ac)
        {
            ac.AiController.SetAiStatus(AiEnum.PlayerAiStatus.CAST_SKILL);
        }

        protected virtual void PushCacheElem(CacheAiBehavior Elem)
        {
            this._CacheAiBehaviorList.Clear();
            this._CacheAiBehaviorList.Add(Elem);
        }

        private void RegisterToDungeonMgr()
        {
            GlobalAPI.facade.Add(9, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Add(10, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Add(12, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Add(13, new NoticeListener(this.UpdateAiByDungeon));
        }

        public virtual void SetAi(bool value)
        {
            Log.AI(base.gameObject, " SetAiEnable false " + value);
            if (value != this.IsAiEnable)
            {
                this._lastIsAiEnable = this.IsAiEnable;
                this.IsAiEnable = value;
            }
        }

        protected abstract void SetAiScriptType();
        protected virtual void SetAiStatus(AiEnum.MonsterAiStatus ai_status)
        {
            this.SetAiStatusButNotClearTarget(ai_status);
            this.CleanTargetDisplay();
        }

        protected virtual void SetAiStatus(AiEnum.PlayerAiStatus ai_status)
        {
            this.SetAiStatusButNotClearTarget(ai_status);
            this.CleanTargetDisplay();
        }

        protected virtual void SetAiStatus(AiEnum.PrivateAiStatus ai_status)
        {
            this.SetAiStatusButNotClearTarget(ai_status);
            this.CleanTargetDisplay();
        }

        protected virtual void SetAiStatus(AiEnum.SummonAiStatus ai_status)
        {
            this.SetAiStatusButNotClearTarget(ai_status);
            this.CleanTargetDisplay();
        }

        public virtual void SetAiStatusButNotClearTarget(AiEnum.MonsterAiStatus ai_status)
        {
            this._ai_status = (int) ai_status;
        }

        public virtual void SetAiStatusButNotClearTarget(AiEnum.PlayerAiStatus ai_status)
        {
            this._ai_status = (int) ai_status;
        }

        public virtual void SetAiStatusButNotClearTarget(AiEnum.PrivateAiStatus ai_status)
        {
            this._ai_status = (int) ai_status;
        }

        public virtual void SetAiStatusButNotClearTarget(AiEnum.SummonAiStatus ai_status)
        {
            this._ai_status = (int) ai_status;
        }

        public virtual void SetAiToPrevious()
        {
            this.SetAi(this._lastIsAiEnable);
        }

        public virtual void SetBattleState(bool value)
        {
            this.IsInBattle = value;
        }

        public abstract void SetTargetDisplay(ActionDisplay ad);
        protected abstract bool SetTargetDisplay(bool isEvaluating = false);
        protected virtual void SetTargetDisplay(Func<bool> checker)
        {
            if (checker())
            {
                this.SetTargetDisplay(false);
            }
        }

        public virtual void SkilledSuccessfully(SysSkillBaseVo skillBaseVo, List<PDamage> damageList, float time = 0)
        {
            time = (time == 0f) ? this._nowTime : time;
            this.LastSkilledSuccessfullyTime = time;
            this.DamageList = damageList;
        }

        private void Start()
        {
            if (!this._isInitialized)
            {
                this.Init();
                this._isInitialized = true;
            }
        }

        protected virtual void Targeted()
        {
        }

        private void Tick(float timeElapsed)
        {
            if (((this._tick += timeElapsed) >= this._loop_interval) && (!AppMap.Instance.IsInMainCity && !MapMode.StartAutoMove))
            {
                this._nowStatusHash = this.MeController.StatuController.CurStatuNameHash;
                this._nowStatus = this.MeController.StatuController.CurrentStatu;
                this.PrepareWork();
                if (this.CheckCanUseAi())
                {
                    this.SetTargetDisplay(this.IsNeedToSetNewTargetDisplay());
                    this.AiStateDecision(this.CheckShouldSkipThink(), this._tick);
                    this._tick = 0f;
                }
            }
        }

        private void UnregisterFromDungeonMgr()
        {
            GlobalAPI.facade.Remove(9, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Remove(10, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Remove(12, new NoticeListener(this.UpdateAiByDungeon));
            GlobalAPI.facade.Remove(13, new NoticeListener(this.UpdateAiByDungeon));
        }

        private void Update()
        {
            if (this._isInitialized)
            {
                this._nowTime = Time.time;
                this.Tick(Time.deltaTime);
            }
        }

        private void UpdateAiByDungeon(int evtType, int v1, int v2, object data)
        {
            if (DungeonMgr.Instance.isPlaying)
            {
                this.SetAiToPrevious();
            }
            else
            {
                this.ForceToStopAIAndAllBehavior();
            }
        }

        public void UpdateCamp()
        {
            this.BaseRoleVo = this.MeController.Me.GetMeVoByType<com.game.vo.BaseRoleVo>();
        }

        protected com.game.vo.BaseRoleVo BaseRoleVo
        {
            get
            {
                return this._baseRoleVo;
            }
            set
            {
                this._baseRoleVo = value;
                this.MyCamp = value.Camp;
            }
        }

        public List<PDamage> DamageList { get; set; }

        public bool IsAiEnable
        {
            get
            {
                return this._isAiEnable;
            }
            set
            {
                Log.AI(base.gameObject, " Who Clear AI Here " + value);
                this._isAiEnable = value;
                this.ClearCacheAiBehavior();
            }
        }

        public bool IsInBattle { get; set; }

        public float LastBeAttackedTime { get; protected set; }

        public float LastSkilledSuccessfullyTime { get; protected set; }

        public float LastUseAttackTime { get; protected set; }

        public float LastUseSkillTime { get; protected set; }

        protected uint MyCamp { get; private set; }

        protected sealed class CacheAiBehavior
        {
            public int attack_id;
            public int cacheType;
            public AfterCastSkill callback = new AfterCastSkill(AiControllerBase.CallbackSetAiThink);
            public int idx = -1;
            public ActionDisplay lastDisplay;
            public BeforeCastSkill preparework = new BeforeCastSkill(AiControllerBase.PrepareworkSetAiCastSkill);
            public uint skill_id;
        }

        protected sealed class KV
        {
            public ActionDisplay ad;
            public float distance;

            public KV(ActionDisplay display, float dis)
            {
                this.ad = display;
                this.distance = dis;
            }
        }
    }
}

